package com.expert.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.expert.Mapper.ScoreDetailedMapper;
import com.expert.context.BaseContext;
import com.expert.dto.AddScoreDTO;
import com.expert.enums.ProjectStatus;
import com.expert.exception.AddException;
import com.expert.pojo.Expert;
import com.expert.pojo.Project;
import com.expert.pojo.ScoreDetailed;
import com.expert.service.ExpertService;
import com.expert.service.ExtractResultService;
import com.expert.service.ProjectService;
import com.expert.service.ScoreDetailedService;
import com.expert.vo.ScoreMoreInfo;
import com.expert.vo.ShowScoreDataVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @ClassName: ScoreDetailedServiceImpl
 * @Author: cxs
 * @Date: 2024/03/30 16:04
 * @Description:
 **/
@Service
public class ScoreDetailedServiceImpl extends ServiceImpl<ScoreDetailedMapper,ScoreDetailed> implements ScoreDetailedService {


    @Autowired
    ExtractResultService extractResultService;
    @Autowired
    ExpertService expertService;
    @Autowired
    ProjectService projectService;
    /**
     * 添加项目评价
     *
     * @param addScoreDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addScore(AddScoreDTO addScoreDTO) {
        if (addScoreDTO.getScore()==null||addScoreDTO.getProjectDetail()==null|| "".equals(addScoreDTO.getProjectDetail())){
            throw new AddException("项目评分及项目评价不能为空");
        }
        Long count = this.lambdaQuery().eq(ScoreDetailed::getExpertId, BaseContext.getCurrentId())
                .eq(ScoreDetailed::getProjectId, addScoreDTO.getProjectId()).count();
        if (count>0){
            throw  new AddException("该项目已评价,不能重复评价");
        }
        Expert expert = this.expertService.lambdaQuery().eq(Expert::getExpertUser, BaseContext.getCurrentId()).one();
        ScoreDetailed scoreDetailed=ScoreDetailed.builder()
                .score(addScoreDTO.getScore())
                .projectId(addScoreDTO.getProjectId())
                .expertId(expert.getId())
                .detailed(addScoreDTO.getProjectDetail())
                .createUser(BaseContext.getCurrentId())
                .updateUser(BaseContext.getCurrentId())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
        this.save(scoreDetailed);
        //获取所有分数
        List<ScoreDetailed> list = this.lambdaQuery().eq(ScoreDetailed::getProjectId, addScoreDTO.getProjectId()).list();
        AtomicReference<Double> total= new AtomicReference<>(0.0);

        list.forEach(score->{
            total.updateAndGet(v -> v + score.getScore());
        });
        Project project = this.projectService.getById(addScoreDTO.getProjectId());
        if (list.size()==project.getProjectReviewNumber()){
            project.setProjectStatus(ProjectStatus.REVIEWED.getCode());
        }
        project.setProjectScore(total.get()/list.size());
        this.projectService.updateById(project);
    }

    /**
     * 查询评分列表
     *
     * @param page
     * @param pageSize
     * @param expertName
     * @param projectName
     * @return
     */
    @Override
    public Page<ShowScoreDataVo> showScoreList(Integer page, Integer pageSize, String expertName, String projectName) {
        List<Long> expertList = new ArrayList<>(this.expertService.lambdaQuery()
                .like(StringUtils.isNotEmpty(expertName), Expert::getExpertName, expertName)
                .list().stream().map(Expert::getId).toList());
        expertList.add(-1L);
        List<Long> projectList = new ArrayList<>(this.projectService.lambdaQuery().like(StringUtils.isNotEmpty(projectName), Project::getProjectName, projectName)
                .list().stream().map(Project::getId).toList());
        projectList.add(-1L);
        long count = this.projectService.count();
        long expertCount = this.expertService.count();

        Page<ScoreDetailed> scoreDetailedPage=new Page<>(page,pageSize);
        page(scoreDetailedPage,new LambdaQueryWrapper<ScoreDetailed>()
                .in(expertCount>expertList.size()-1,ScoreDetailed::getExpertId,expertList)
                .in(count>projectList.size()-1,ScoreDetailed::getProjectId,projectList));
        Page<ShowScoreDataVo> showScoreDataVoPage=new Page<>();
        BeanUtils.copyProperties(scoreDetailedPage,showScoreDataVoPage);
        List<ShowScoreDataVo> showScoreDataVos = scoreDetailedPage.getRecords().stream().map(score -> {
            ShowScoreDataVo showScoreDataVo = new ShowScoreDataVo();
            BeanUtils.copyProperties(score, showScoreDataVo);
            showScoreDataVo.setReviewTime(score.getCreateTime());
            Project project = this.projectService.getById(score.getProjectId());
            showScoreDataVo.setProjectName(project.getProjectName());
            showScoreDataVo.setProjectId(project.getId());
            showScoreDataVo.setProjectStatus(project.getProjectStatus());
            Expert expert = this.expertService.getById(score.getExpertId());
            showScoreDataVo.setExpertId(expert.getId());
            showScoreDataVo.setExpertPhone(expert.getExpertPhone());
            showScoreDataVo.setExpertName(expert.getExpertName());
            return showScoreDataVo;
        }).toList();
        showScoreDataVoPage.setRecords(showScoreDataVos);
        return showScoreDataVoPage;
    }

    /**
     * 更多评分
     *
     * @param id
     * @return
     */
    @Override
    public ScoreMoreInfo showMore(Long id) {
        ScoreDetailed scoreDetailed = this.getById(id);
        ScoreMoreInfo moreInfo=new ScoreMoreInfo();
        BeanUtils.copyProperties(scoreDetailed,moreInfo);
        moreInfo.setReviewTime(scoreDetailed.getCreateTime());
        moreInfo.setProjectName(this.projectService.getById(scoreDetailed.getProjectId()).getProjectName());
        moreInfo.setExpertName(this.expertService.getById(scoreDetailed.getExpertId()).getExpertName());
        return moreInfo;
    }
}
